﻿using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.EventSystems;

namespace MiHoMiao.Mono.UGUI.DraggableSlider
{
    public class DraggableSlider : MonoBehaviour, IPointerDownHandler
    {
        public enum DraggableSliderType : byte
        {
            Horizontal,
            Vertical,
            HorizontalAndVertical
        }

        public DraggableSliderType DraggableType;
        public Vector2 HorizontalRange = new Vector2(float.MinValue, float.MaxValue);
        public Vector2 VerticalRange = new Vector2(float.MinValue, float.MaxValue);

        private Vector3 m_StartPosition;
        
        public void OnPointerDown(PointerEventData eventData)
        {
            if (eventData.button != PointerEventData.InputButton.Left) return;
            m_StartPosition = Input.mousePosition;
            if (DraggableType is DraggableSliderType.Horizontal) FollowMouseHorizontal().Forget();
            else if (DraggableType is DraggableSliderType.Vertical) FollowMouseVertical().Forget();
            else FollowMouseHorizontalAndVertical().Forget();
            return;
            
            async UniTaskVoid FollowMouseHorizontal()
            {
                while (Input.GetMouseButton(0))
                {
                    Vector3 target = transform.localPosition + Input.mousePosition - m_StartPosition;
                    m_StartPosition = Input.mousePosition;
                    float targetX = Mathf.Clamp(target.x, HorizontalRange.x, HorizontalRange.y);
                    transform.localPosition = new Vector3(targetX, transform.localPosition.y);
                    await UniTask.NextFrame();
                }
            }
            async UniTaskVoid FollowMouseVertical()
            {
                while (Input.GetMouseButton(0))
                {
                    Vector3 target = transform.localPosition + Input.mousePosition - m_StartPosition;
                    m_StartPosition = Input.mousePosition;
                    float targetY = Mathf.Clamp(target.y, VerticalRange.x, VerticalRange.y);
                    transform.localPosition = new Vector3(transform.localPosition.x, targetY);
                    await UniTask.NextFrame();
                }
            }
            async UniTaskVoid FollowMouseHorizontalAndVertical()
            {
                while (Input.GetMouseButton(0))
                {
                    Vector3 target = transform.localPosition + Input.mousePosition - m_StartPosition;
                    m_StartPosition = Input.mousePosition;
                    float targetX = Mathf.Clamp(target.x, HorizontalRange.x, HorizontalRange.y);
                    float targetY = Mathf.Clamp(target.y, VerticalRange.x, VerticalRange.y);
                    transform.localPosition = new Vector3(targetX, targetY);
                    await UniTask.NextFrame();
                }

            }
        }

    }
}